﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using ChineseRemainderTheorem.Core;
using ChineseRemainderTheorem.Mvvm;

namespace ChineseRemainderTheorem.ViewModels
{
    public class ShareViewModel : BaseViewModel
    {
        #region Fields

        #region Services

        private readonly ISecretSharingService _secretSharingService;

        #endregion

        #region Containers for bindable properties

        private BigInteger _secret;

        private int _usersCountToRestore;

        private int _secretPartsCount;

        private ObservableCollection<SecretSharingOperation> _secretParts;

        private bool _isCalculating;

        #endregion

        #region Commands

        private ICommand _shareCommand;

        #endregion

        #endregion

        #region Properties

        public BigInteger Secret
        {
            get { return _secret; }
            set { SetProperty(ref _secret, value, "Secret"); }
        }

        public int UsersCountToRestore
        {
            get { return _usersCountToRestore; }
            set { SetProperty(ref _usersCountToRestore, value, "UsersCountToRestore"); }
        }

        public int SecretPartsCount
        {
            get { return _secretPartsCount; }
            set { SetProperty(ref _secretPartsCount, value, "SecretPartsCount"); }
        }

        public bool IsCalculating
        {
            get { return _isCalculating; }
            set { SetProperty(ref _isCalculating, value, "IsCalculating"); }
        }

        public ObservableCollection<SecretSharingOperation> SecretParts
        {
            get { return _secretParts; }
            set { SetProperty(ref _secretParts, value, "SecretParts"); }
        }

        public ICommand ShareCommand
        {
            get { return _shareCommand ?? (_shareCommand = new SimpleCommand(o => OnShare(), o => CanShare())); }
        }

        #endregion

        #region Constructors

        public ShareViewModel(ISecretSharingService secretSharingService)
        {
            if (ReferenceEquals(secretSharingService, null))
            {
                throw new ArgumentNullException("secretSharingService");
            }
            _secretSharingService = secretSharingService;
        }

        #endregion

        #region Methods

        private async void OnShare()
        {
            IsCalculating = true;
            try
            {
                SecretSharingOperation[] result =
                    await _secretSharingService.ShareAsync(Secret, UsersCountToRestore, SecretPartsCount);
                SecretParts = new ObservableCollection<SecretSharingOperation>(result);
            }
            catch (Exception ex)
            {
                Application.Current.Dispatcher.BeginInvoke(
                    (Func<Window, string, string, MessageBoxButton, MessageBoxResult>) (MessageBox.Show),
                    Application.Current.MainWindow,
                    ex.Message, "Упс, ошибка...", MessageBoxButton.OK);
            }
            finally
            {
                IsCalculating = false;    
            }
            
        }

        private bool CanShare()
        {
            return UsersCountToRestore > 2 && UsersCountToRestore < 19 && SecretPartsCount > 3 && SecretPartsCount < 20;
        }

        #endregion
    }
}